package drds.binlog.binlog_event.event;

import drds.binlog.binlog_event.LogByteBlock;
import drds.binlog.binlog_event.LogEvent;
import drds.binlog.common.Authors;
import drds.common.Author;
import lombok.Getter;
import lombok.Setter;

import java.nio.ByteBuffer;
import java.util.UUID;

/**
 * @since mysql 5.6 / mariadb10
 */
@Author(name = Authors.LI_YANG)
public class GtidLogEvent extends LogEvent
{

    // / length of the commit_flag in event encoding
    public static final int encoded_flag_length = 1;
    // / length of sid in event encoding
    public static final int encoded_sid_length = 16;
    public static final int logical_timestamp_type_code = 2;

    @Setter
    @Getter
    private boolean commitFlag;
    @Setter
    @Getter
    private UUID sid;
    @Setter
    @Getter
    private long gno;
    @Setter
    @Getter
    private Long lastCommitted;
    @Setter
    @Getter
    private Long sequenceNumber;

    public GtidLogEvent(LogHeader logHeader, LogByteBlock logByteBlock, FormatDescriptionLogEvent formatDescriptionLogEvent)
    {
        super(logHeader);

        final int commonHeaderLength = formatDescriptionLogEvent.commonHeaderLength;
        // final int postHeaderLengths = descriptionEvent.postHeaderLengths[headerPacket.logType
        // - 1];

        logByteBlock.setIndexAsOriginIndexAndOffset(commonHeaderLength);
        commitFlag = (logByteBlock.get1UnsignedIntByIndex() != 0); // ENCODED_FLAG_LENGTH

        byte[] bytes = logByteBlock.getBytesByIndex(encoded_sid_length);
        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
        long high = byteBuffer.getLong();
        long low = byteBuffer.getLong();
        sid = new UUID(high, low);

        gno = logByteBlock.getLittleEndian8SignedLongByIndex();

        // support gtid lastCommitted and sequenceNumber
        // fix bug #776
        if (logByteBlock.hasRemaining() && logByteBlock.remaining() > 16 && logByteBlock.get1UnsignedIntByIndex() == logical_timestamp_type_code)
        {
            lastCommitted = logByteBlock.getLittleEndian8SignedLongByIndex();
            sequenceNumber = logByteBlock.getLittleEndian8SignedLongByIndex();
        }

        // ignore gtid info read
        // sid.copy_from((uchar *)ptr_buffer);
        // ptr_buffer+= ENCODED_SID_LENGTH;
        //
        // // SIDNO is only generated if needed, in get_sidno().
        // spec.gtid.sidno= -1;
        //
        // spec.gtid.gno= uint8korr(ptr_buffer);
        // ptr_buffer+= ENCODED_GNO_LENGTH;
    }


    public String getGtidString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(sid.toString()).append(":");
        sb.append(gno);
        return sb.toString();
    }
}
